home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / pascal / ghostbbs.zip / BB3.PAS < prev    next >
Pascal/Delphi Source File  |  1980-01-01  |  35KB  |  1,184 lines

  1. { I was getting close to bumping up on the 64K limit  (though Im not
  2.   there yet), so i left procedures sysoponly and filesys as
  3.   overlay procedures }
  4.  
  5. procedure sysoponly;
  6. { allows sysop to edit user stats and parms from local
  7.   or remote location.                                  }
  8.   var temp: char;
  9.       temprec : sysid;
  10.       editno : integer;
  11.  
  12.   procedure display_user;
  13.   { display pertinent user stats on screen for editing }
  14.   var s:longname;
  15.   begin
  16.      with temprec do
  17.        begin
  18.          clearsc;
  19.          lineout('Editing user #'+itoa(editno));
  20.          if intlg = '***' then lineout('Not yet verified')
  21.            else lineout('Verified '+intlg);
  22.          lineout('1.) Name           '+user);
  23.          lineout('2.) Realname       '+user2);
  24.          lineout('3.) Password       '+pass);
  25.          lineout('4.) Street Address '+addr);
  26.          lineout('5.) City           '+city);
  27.          lineout('6.) State & Zip    '+szip);
  28.          lineout('7.) Phone number   '+phnn);
  29.          lineout('8.) Last log on    '+lsto);
  30.          lineout('9.) Access level   '+itoa(acc));
  31.          lineout('10.) Spec. access  '+itoa(speca));
  32.          lineout('11.) Downloads     '+itoa(dld));
  33.          lineout('12.) Uploads       '+itoa(uld));
  34.          lineout('13.) Msgs posted   '+itoa(mptd));
  35.          lineout('14.) Times on      '+itoa(lgdn));
  36.        end;
  37.   end;
  38.  
  39.   procedure edit_stats(number:integer);
  40.   var i,j: integer;
  41.       s  : longname;
  42.       ch : char;
  43.   begin
  44.     editno := number;
  45.     display_user;
  46.     repeat
  47.       s := allcaps(getinput('[E]dit [S]ave [A]bort re[F]resh [R]emove [V]erify ',1,echo));
  48.       ch := s[1];
  49.       if ch = 'F' then display_user;
  50.       if ch = 'V'
  51.         then begin
  52.           clock(year,month, date, hour, min);
  53.           temprec.intlg := time(year,month, date, hour, min);
  54.           temprec.acc := reg;
  55.         end;
  56.       if ch = 'S' then
  57.         begin
  58.           assign(idfile, 'IDS.BBS');
  59.           reset(idfile);
  60.           seek(idfile, number);
  61.           write(idfile, temprec);
  62.           close(idfile);
  63.         end;
  64.       if ch = 'R' then
  65.         begin
  66.           with temprec do
  67.             begin
  68.               user := space;
  69.               user2 := space;
  70.               addr := space;
  71.               city := space;
  72.               szip := space;
  73.               phnn := space;
  74.               lsto := space;
  75.               dld := 0;
  76.               uld := 0;
  77.               mptd := 0;
  78.               lgdn := 0;
  79.               fillchar(lstm,sizeof(lstm),#0);
  80.               pass := '***';
  81.               intlg := '***';
  82.               acc := 0;
  83.               speca := 0;
  84.             end;
  85.           assign(idfile, 'IDS.BBS');
  86.           reset(idfile);
  87.           seek(idfile, number);
  88.           write(idfile, temprec);
  89.           close(idfile);
  90.         end;
  91.       if ch = 'E' then
  92.         begin
  93.           repeat
  94.             i := getint(14,0,'Edit which? ');
  95.               case i of
  96.                 1..8 : s:=allcaps(getinput('New ',25,echo));
  97.                 9    :  j:=getint(5,0,'New ');
  98.                 10..14: j:=getint(255,0,'New ');
  99.               end; {case}
  100.               with temprec do
  101.                 case i of
  102.                   1 :  user := s;
  103.                   2 :  user2 := s;
  104.                   3 :  pass := s;
  105.                   4 :  addr := s;
  106.                   5 :  city := s;
  107.                   6 :  szip := s;
  108.                   7 :  phnn := s;
  109.                   8 :  lsto := s;
  110.                   9 :  acc := j;
  111.                   10:  speca := j;
  112.                   11:  dld := j;
  113.                   12:  uld := j;
  114.                   13:  mptd := j;
  115.                   14:  lgdn := j;
  116.                 end; {case}
  117.           until ((i = 0) or (not cts));
  118.         end;
  119.     until ((ch in ['A','S','R']) or (not cts));
  120.   end;
  121.  
  122.   procedure edit_user;
  123.     var
  124.      errcode, number: integer;
  125.      temp: longname;
  126.      found : boolean;
  127.     begin
  128.       repeat
  129.         found := false;
  130.         temp := allcaps(getinput('User name or # ? ',25,echo));
  131.         val(temp,number,errcode);
  132.         if errcode = 0 then found := true
  133.                        else find_name(temp,number,found);
  134.         editno := number;
  135.         if found
  136.           then begin
  137.           assign(idfile, 'IDS.BBS');
  138.           reset(idfile);
  139.           seek(idfile, number);
  140.           {$I-}
  141.           read(idfile, temprec);
  142.           {$I+}
  143.           if ioresult <> 0 then found := false;
  144.           close(idfile);
  145.         end;
  146.         if (found and (temp <> '')) then edit_stats(number)
  147.                                     else lineout(temp + ' Not found ');
  148.       until ((temp = '') or (not cts));
  149.     end;
  150.  
  151. procedure verify_users;
  152. var number: integer;
  153.     s :  name;
  154.     ch, ch1 : char;
  155. begin
  156.   repeat
  157.     s:=allcaps(getinput('A)ll or N)ew ',10,echo));
  158.     ch := s[1];
  159.   until ((ch in ['A','N']) or (not cts));
  160.   number := 0;
  161.   while  ((ch1 <> 'N') and cts ) do
  162.   begin
  163.     assign(idfile,'IDS.BBS');
  164.     reset(idfile);
  165.     seek(idfile,number);
  166.     {$I-}
  167.     read(idfile,temprec);
  168.     {$I+}
  169.     if ioresult <> 0 then
  170.       begin
  171.         close(idfile);
  172.         exit;
  173.       end;
  174.     close(idfile);
  175.     if ((ch = 'N') and ( temprec.intlg = '***') and (temprec.pass <> '***')) then edit_stats(number);
  176.     if (ch = 'A') then edit_stats(number);
  177.     number := number + 1;
  178.     if ch = 'A' then ch1 := getcap('Continue (Y/N) ? ');
  179.   end;
  180. end;
  181.  
  182.   begin { sysoponly }
  183.     repeat
  184.       temp := getcap('[E]dit, [V]erify, [R]ead Log ? ');
  185.       case temp of
  186.         'E': edit_user;
  187.         'V': verify_users;
  188.         'R': read_userlog;
  189.       end;
  190.     until not ((temp in ['C','E','R']) and cts);
  191.   end;
  192.  
  193. overlay procedure filesys;
  194. { does all the xmodem u/d loads and ascii file transfers}
  195.   const
  196.     soh = 1;
  197.     eot = 4;
  198.     ack = 6;
  199.     nak = $15;
  200.     can = $18;
  201.     C   = $43;
  202.     maxnumfilesects = 20;
  203.  
  204. type
  205.  str40  = string[40];
  206.  str30  = string[30];
  207.  str20  = string[20];
  208.  sect1  = record
  209.               sectt       : str30;
  210.               secdir      : str40;
  211.               sect_access : byte;
  212.               spec_access : byte;
  213.          end;
  214.  
  215.  sectname = array[1..maxnumfilesects] of sect1;
  216.  
  217.     channel = array[0..127] of byte;
  218.  
  219.   var
  220.     sect : sectname;
  221.     filebuff: array [0..16] of channel;
  222.     datafile: file;
  223.     chksum: byte;
  224.     CRC: integer;
  225.     crcmode: boolean;
  226.     comch: char;
  227.     filename : line;
  228.     sectnum : byte;
  229.  
  230. procedure getsects;
  231. var textfile : text;
  232.     loop : byte;
  233. begin
  234. assign(textfile,'bbsinfo\files.cnf');
  235. reset(textfile);
  236. for loop := 1 to numfilesects do
  237.   begin
  238.     readln(textfile,sect[loop].sectt);
  239.     readln(textfile,sect[loop].secdir);
  240.     read(textfile,sect[loop].sect_access);
  241.     readln(textfile,sect[loop].spec_access);
  242.   end;
  243. close(textfile);
  244. end;
  245.  
  246.   procedure xmit(x:byte);
  247.     begin
  248.       xmitchar(chr(x));
  249.     end;
  250.  
  251.   function inbyte: byte;
  252.     var temp: char;
  253.     begin
  254.       repeat until inready or not cts;
  255.       if keypressed then read(kbd, temp) else temp := recvchar;
  256.       inbyte := ord(temp);
  257.     end;
  258.  
  259.   procedure calcCRC(data:byte);
  260.     var
  261.       carry: boolean;
  262.       i: byte;
  263.     begin
  264.       chksum := lo(chksum + data);
  265.       for i := 0 to 7 do begin
  266.         carry := (crc and $8000) <> 0;
  267.         crc := crc shl 1;
  268.         if (data and $80) <> 0 then crc := crc or $0001;
  269.         if carry then crc := crc xor $1021;
  270.         data := lo(data shl 1);
  271.       end;
  272.     end;
  273.  
  274.   procedure sendcalc(ch : byte);
  275.     begin
  276.       xmit(ch);
  277.       calcCRC(ch);
  278.     end;
  279.  
  280.   procedure acknak(var inch: byte; time: integer);
  281.     var loop, loopend: integer;
  282.     begin
  283.       loopend := 100 * time;
  284.       loop := 0;
  285.       inch := 0;
  286.       repeat
  287.         delay(10);
  288.         if inready then inch := inbyte;
  289.         loop :=loop + 1;
  290.       until (inch in [ack, nak, can, C]) or (loop >= loopend) or not cts;
  291.     end;
  292.  
  293.   function acknakout(ch : byte): boolean;
  294.     var  times, loops: integer;
  295.     begin
  296.       times := 0;
  297.       repeat
  298.         loops := 0;
  299.         xmit(ch);
  300.         while (loops < 10) and not timedin do loops := loops + 1;
  301.         times := times + 1;
  302.       until inready or (times > 9) or not cts;
  303.       acknakout := inready and cts;
  304.     end;
  305.  
  306.   procedure download(var successful: boolean);
  307.     var
  308.       inch, loop: byte;
  309.       blocknum, period, tries: integer;
  310.       done: boolean;
  311.       temp: line;
  312.       dtime, dsize: real;
  313.     begin
  314.       reset(datafile);
  315.       dsize := longfilesize(datafile);
  316.       dtime := (dsize * 1.30 * 1200/baud) / 60;
  317.       lineout('Ready for XMODEM transfer:');
  318.       str(dsize:8:0, temp);
  319.       lineout('File open:' + temp + ' Blocks');
  320.       str(dtime:3:2, temp);
  321.       lineout('Download Time is approx. ' + temp + ' Minutes.');
  322.       calcconnect(usehour,usemin);
  323.       if ((((usehour * 60) + (today_timeon +usemin)) > (maxminon - dtime))
  324.              and (access < prefuser))
  325.         then begin
  326.           lineout(space);
  327.           lineout('Sorry Swab, You don''t have enough time left');
  328.           successful := false;
  329.           close(datafile);
  330.           exit;
  331.         end;
  332.       lineout('To cancel: type CTL-X until you return to command prompt.');
  333.       blockread(datafile, filebuff[0], 1);
  334.       done := false;
  335.       tries := 0;
  336.       blocknum := 1;
  337.       crcmode := false;
  338.       repeat
  339.         acknak(inch, 60);
  340.         if inch = 0 then inch := can;
  341.         if inch = C then begin
  342.           crcmode := true;
  343.           writeln('CRC mode requested');
  344.         end;
  345.         if inch = ack then begin
  346.           if eof(datafile) then done := true else begin
  347.             write(cr + 'Sent #', blocknum:4);
  348.             blockread(datafile, filebuff[0], 1);
  349.             blocknum := blocknum + 1;
  350.             tries := 0;
  351.           end;
  352.         end
  353.         else tries := tries + 1;
  354.         if (inch <> can) and cts and not done then begin
  355.           xmit(soh);
  356.           xmit(lo(blocknum));
  357.           xmit(255-lo(blocknum));
  358.           chksum := 0;
  359.           crc := 0;
  360.           for loop := 0 to 127 do sendcalc(filebuff[0][loop]);
  361.           calcCRC(0);
  362.           calcCRC(0);
  363.           if crcmode then begin xmit(hi(crc)); xmit(lo(crc)); end
  364.             else xmit(chksum);
  365.         end;
  366.         if tries = 5 then crcmode := not crcmode;
  367.       until (inch = can) or done or (tries= 10) or not cts;
  368.       successful := done;
  369.       tries := 0;
  370.       if successful and cts then repeat
  371.         xmit(eot);
  372.         acknak(inch, 10);
  373.         tries := tries + 1;
  374.       until (inch=ack) or (tries > 10) or not cts;
  375.       if cts and (inch <> can) and not successful then xmit(can);
  376.       close(datafile);
  377.       if successful then lineout(cr + lf + 'Download Successful! ')
  378.                     else lineout(cr + lf + 'Download NOT Successful ');
  379.     end;
  380.  
  381.   function recchar(var error: boolean): byte;
  382.     var temp: byte;
  383.     begin
  384.       temp := 0;
  385.       if not cts then error := true;
  386.       if not error then begin
  387.         if not timedin then error := true
  388.         else begin
  389.           temp := inbyte;
  390.           calcCRC(temp);
  391.           recchar := temp;
  392.         end;
  393.       end;
  394.     end;
  395.  
  396.   procedure clearline;
  397.     var junk: byte;
  398.     begin
  399.       while timedin do junk := inbyte;
  400.     end;
  401.  
  402. {$I-}
  403.   procedure upload(var successful: boolean);
  404.     var
  405.       blocknum, tries, byteloc        : integer;
  406.       comp, locblock, crc2            : integer;
  407.       fatal, error, done              : boolean;
  408.       opening, inch, locrc            : byte;
  409.       hicrc, csum2, mode              : byte;
  410.  
  411.     begin
  412.       lineout('Beginning XMODEM protocol upload:');
  413.       lineout('To cancel: type CTRL-X until you return to command prompt.');
  414.       lineout('Hit RETURN when finished');
  415.       tries := 0;
  416.       done := false;
  417.       opening := 0;
  418.       locblock := 1;
  419.       rewrite(datafile);
  420.       fatal := ioresult > 0;
  421.       if crcmode then mode := C else mode := nak;
  422.       if cts and not fatal then fatal := not acknakout(mode);
  423.       while cts and not (done or fatal) do begin
  424.         tries := tries + 1;
  425.         error := false;
  426.         opening := recchar(error);
  427.         if opening = can then fatal := true;
  428.         if opening = eot then done := true;
  429.         if (opening <> eot) and (opening <> soh) and not fatal
  430.           then error := true;
  431.         if cts and not (error or fatal or done) then begin
  432.           blocknum := recchar(error);
  433.           comp := recchar(error);
  434.           if lo(comp + blocknum + opening) <> 0 then error := true;
  435.           byteloc := 0;
  436.           crc := 0;
  437.           chksum := 0;
  438.           while (byteloc < 128) and not (error or fatal) do begin
  439.             filebuff[0][byteloc] := recchar(error);
  440.             byteloc := byteloc + 1;
  441.           end;
  442.           if cts and not (error or fatal) then begin
  443.             calcCRC(0);
  444.             calcCRC(0);
  445.             crc2 := crc;
  446.             csum2 := chksum;
  447.             hicrc := recchar(error);
  448.             if crcmode then begin
  449.               locrc := recchar(error);
  450.               if (lo(crc2) <> locrc) or (hi(crc2) <> hicrc) then error := true;
  451.             end else if csum2 <> hicrc then error := true;
  452.             if (lo(locblock) <> blocknum)
  453.               and (lo(locblock) <> lo(blocknum+1))
  454.               and not error
  455.               then fatal := true;
  456.             if (lo(locblock) = blocknum) and not (error or fatal) then begin
  457.               blockwrite(datafile, filebuff[0], 1);
  458.               write(cr + ' Received #', locblock:5);
  459.               if IOresult <> 0 then fatal := true;
  460.               tries := 0;
  461.               locblock := locblock + 1;
  462.             end;
  463.           end;
  464.         end;
  465.         if not (fatal or error) then purgeline else clearline;
  466.         if done or not (error or fatal) then fatal := not acknakout(ack);
  467.         if error and not fatal then begin
  468.           fatal := not acknakout(nak);
  469.           if tries > 6 then crcmode := not crcmode;
  470.         end;
  471.       end;
  472.       if fatal then xmit(can);
  473.       if done then xmit(ack);
  474.       close(datafile);
  475.       successful := (IOresult = 0) and done and not fatal;
  476.       if not successful then erase(datafile);
  477.       if successful then lineout(cr + lf + 'Upload Successful!');
  478.     end;
  479.  
  480.   procedure storebuff(var buffernum: byte; var paused, aborted: boolean);
  481.     var loop: byte;
  482.     begin
  483.       loop := 0;
  484.       while (loop < buffernum) and not aborted do begin
  485.         blockwrite(datafile, filebuff[loop], 1);
  486.         if IOresult > 0 then aborted := true;
  487.         loop := loop + 1;
  488.       end;
  489.       if buffernum in [1..16] then filebuff[0] := filebuff[buffernum];
  490.       buffernum := 0;
  491.       repeat xmit(17) until timedin;
  492.       paused := false;
  493.     end;
  494.  
  495.   procedure textcap(var successful: boolean);
  496.     var
  497.       buffernum, where, loop  : byte;
  498.       cc, cz, paused          : boolean;
  499.       withecho, done, aborted : boolean;
  500.       temp                    : byte;
  501.     begin
  502.       withecho := (getcap('Do you want your text echoed (Y/N) ? ') = 'Y');
  503.       lineout('Beginning text capture: 3 CTRL-Cs abort, 3 CTRL-Zs end.');
  504.       cc := false;
  505.       cz := false;
  506.       done := false;
  507.       paused := false;
  508.       buffernum := 0;
  509.       where := 0;
  510.       rewrite(datafile);
  511.       aborted := (IOresult > 0);
  512.       while cts and not (done or aborted) do begin
  513.         if paused then storebuff(buffernum, paused, aborted);
  514.         temp := inbyte and $7f;
  515.         if not cts then aborted := true;
  516.         if withecho and outready then xmit(temp);
  517.         write(chr(temp));
  518.         if temp = 3 then begin if cc then aborted := true else cc := true; end
  519.           else cc := false;
  520.         if temp = 26
  521.           then begin
  522.             if cz
  523.               then done := true
  524.               else cz := true;
  525.           end else cz := false;
  526.         filebuff[buffernum][where] := temp;
  527.         where := where + 1;
  528.         if where > 127 then begin
  529.           where := 0;
  530.           buffernum := buffernum + 1;
  531.         end;
  532.         if buffernum > 14
  533.           then begin
  534.             paused := true;
  535.             xmit(19);
  536.           end;
  537.         if buffernum > 16 then aborted := true;
  538.       end;
  539.       if done and cts and not aborted then begin
  540.         buffernum := buffernum + 1;
  541.         storebuff(buffernum, paused, aborted);
  542.       end;
  543.       close(datafile);
  544.       if aborted and (IOresult = 0) then erase(datafile);
  545.     successful := done and (IOresult=0) and not aborted;
  546.     end;
  547. {$I+}
  548.  
  549.   function exists(filename:line): boolean;
  550.     var found: boolean;
  551.     begin
  552.       assign(datafile, filename);
  553.       {$I-} reset(datafile) {$I+};
  554.       found := (IOresult = 0);
  555.       if found then close(datafile);
  556.       exists := found;
  557.     end;
  558.  
  559.   function alpha(filename:line): boolean;
  560.     var strpos: integer;
  561.         okay:   boolean;
  562.         dots:   byte;
  563.     begin
  564.       dots := 0;
  565.       okay := true;
  566.       if length(filename) > 0 then
  567.         for strpos := 1 to length(filename) do begin
  568.           if filename[strpos] = '.' then dots := dots + 1;
  569.           if not (filename[strpos] in ['.', '-', '_','#', '0'..'9', 'A'..'Z'])
  570.             then okay := false;
  571.         end;
  572.       if dots > 1 then okay := false;
  573.       alpha := okay;
  574.     end;
  575.  
  576.   function getlegal: line;
  577.     var filename:  line;
  578.         dotpos: integer;
  579.     begin
  580.       repeat
  581.         filename := allcaps(getinput('Enter name of file ? ', 13, echo));
  582.         dotpos := pos('.', filename);
  583.       until (((dotpos < 10) and (dotpos <> 1)
  584.        and (not((dotpos = 0) and (length(filename) > 8)))
  585.        and (not((dotpos > 0) and (length(filename) > dotpos + 3)))
  586.        and alpha(filename)) or (filename = ''));
  587.       getlegal := filename;
  588.     end;
  589.  
  590. procedure listsections;
  591.   var
  592.     loopvar : integer;
  593.     temp    : line;
  594.   begin
  595.     if cts then begin
  596.       canstat := true;
  597.       clearsc;
  598.       lineout('File Sections:' + cr + lf);
  599.       for loopvar := 1 to numfilesects do begin
  600.         lineout(sect[loopvar].sectt);
  601.       end;
  602.       canstat := false;
  603.     end;
  604.   end;
  605.  
  606.   procedure getsect;
  607.     var temp: integer;
  608.         y : boolean;
  609.         x,oldsect : byte;
  610.   begin
  611.       oldsect := sectnum;
  612.       repeat
  613.         temp := getint(numfilesects, 0, 'Which section (0 for list) ? ');
  614.         if temp = 0 then listsections else sectnum := temp;
  615.       until ((temp > 0) and (temp <= numfilesects)) or not cts;
  616.       x := sect[sectnum].sect_access;
  617.       y := (((sect[sectnum].spec_access and special_access) > 0) or
  618.                  (sect[sectnum].spec_access = 0))  ;
  619.       if not ((access >= x) and (y))
  620.          then begin
  621.            lineout('Access Restricted');
  622.            sectnum := oldsect;
  623.          end;
  624.   end;
  625.  
  626.   function subdir : str40;
  627.   begin
  628.     subdir := sect[sectnum].secdir;
  629.   end;
  630.  
  631.   Procedure update_file_dir(updatestr:line);
  632.   var
  633.     errcode : integer;
  634.     dirfile : text;
  635.   begin
  636.     assign(dirfile,subdir + 'dir.bbs');
  637.     {$I-}
  638.     reset(dirfile);
  639.     {$I+}
  640.     errcode := ioresult;
  641.     if errcode <> 0 then close(dirfile);
  642.     if errcode = 0 then append(dirfile)
  643.                    else rewrite(dirfile);
  644.     writeln(dirfile,updatestr);
  645.     close(dirfile);
  646.   end;
  647.  
  648.   procedure addfile;
  649.   var description : line;
  650.     begin
  651.         resetbuff;
  652.         lineout(space);
  653.         lineout('Please describe '+ filename + ' - (40 Characters)');
  654.         lineout('  |---------------------------------------|');
  655.         stringout('-> ');
  656.         description := inputstring(echo,40);
  657.         update_file_dir(filename + ' ' + description);
  658.         update_userlog('UL = ' + filename + ' ' + description);
  659.     end;
  660.  
  661.   procedure newfile(xmodem: boolean);
  662.     var
  663.       successful: boolean;
  664.     begin
  665.       clearsc;
  666.         stringout('Upload: ');
  667.         filename := getlegal;
  668.         if filename <> '' then begin
  669.           if exists(subdir + filename) then lineout('File name in use.')
  670.           else begin
  671.             assign(datafile, subdir + filename);
  672.             if cts then begin
  673.               if xmodem then upload(successful)
  674.                 else textcap(successful);
  675.               if successful then addfile;
  676.               clearline;
  677.               if successful then uploads := uploads + 1
  678.                 else lineout('Fatal transfer error or disk full...');
  679.             end;
  680.           end;
  681.         end;
  682.     end;
  683.  
  684.   function legaltab(prompt: line): boolean;
  685.     begin
  686.       lineout(space);
  687.       stringout(prompt);
  688.       filename := getlegal;
  689.       if ((filename <> '') and (exists(subdir + filename)))
  690.          then begin
  691.            legaltab := true;
  692.            assign(datafile, subdir + filename);
  693.          end
  694.          else begin
  695.            legaltab := false;
  696.            lineout('No such file available.');
  697.          end;
  698.     end;
  699.  
  700.   procedure transmitfile;
  701.     var
  702.       successful,goodfile: boolean;
  703.     begin
  704.       if downloads >= (uploads * 4)
  705.         then lineout('You MUST upload 1 file for every 4 you download!')
  706.         else begin
  707.           if legaltab('Download: ')
  708.             then begin
  709.               download(successful);
  710.               if successful then
  711.                 begin
  712.                   downloads := downloads + 1;
  713.                   update_userlog('DL = ' + filename);
  714.                 end;
  715.             end;
  716.         end;
  717.     end;
  718.  
  719. procedure textdump;
  720.   begin
  721.     if legaltab('ASCII text dump: ')
  722.       then if filename <> ''
  723.         then begin
  724.           outfile(subdir + filename);
  725.           if not cancelled
  726.             then update_userlog('DL = ' + filename);
  727.         end;
  728.   end;
  729.  
  730. procedure disk_space(drive: CHAR);
  731. var
  732.   regs    :  regpack;
  733.   fr,tr   :  REAL;
  734.   temp    :  name;
  735. BEGIN
  736.     WITH regs DO BEGIN
  737.         dx := ord(drive) - 64;
  738.         ah := $36;
  739.         MsDos(regs);                       { call function }
  740.         fr := bx;
  741.         IF ax > 0 THEN begin
  742.           tr := fr * ax * cx;
  743.           str(tr:8:0,temp);
  744.           end
  745.         ELSE temp:= '0'
  746.     END;
  747. lineout('Free Space: '+temp+' Bytes');
  748. END; {disk_space}
  749.  
  750. TYPE
  751. dta_type = record
  752.          reserved : array[1..21] of byte;
  753.              attr : byte;
  754.              time : integer;
  755.              date : integer;
  756.           sizelo1 : byte;
  757.           sizelo2 : byte;
  758.            sizehi : integer;
  759.             fname : array[1..13] of char;
  760.          end;
  761.  
  762. dir_type = record
  763.               attr : byte;
  764.              fname : string[12];
  765.                min : byte;
  766.                hrs : byte;
  767.                day : byte;
  768.              month : byte;
  769.               year : byte;
  770.               size : real;
  771.          end;
  772.  
  773.   str2   = string[2];
  774.   str10  = string[10];
  775.   str64  = string[64];
  776.   str80  = string[80];
  777.  
  778. var
  779.   dta_area      : dta_type;
  780.   asciiz        : str64;
  781.   dir_entries   : dir_type;
  782.  
  783. procedure set_dta;
  784. var r : regpack;
  785. begin
  786.   r.ds := seg(dta_area);
  787.   r.dx := ofs(dta_area);
  788.   r.ah := $1a;
  789.   msdos(r);
  790. end;
  791.  
  792. function msdos4e(attrib:byte; stuff: line):boolean;
  793. var r : regpack;
  794. begin
  795.   asciiz := stuff + #0;
  796.   r.ds := seg(asciiz[1]);
  797.   r.dx := ofs(asciiz[1]);
  798.   r.cx := attrib;
  799.   r.ah := $4e;
  800.   msdos(r);
  801.   msdos4e := (r.flags and 1) = 1;
  802. end;
  803.  
  804. function msdos4f:boolean;
  805. var r : regpack;
  806. begin
  807.   r.ah := $4f;
  808.   msdos(r);
  809.   msdos4f := (r.flags and 1) = 1;
  810. end;
  811.  
  812. procedure showdta;
  813. var   y  : byte;
  814.     temp : str64;
  815. begin
  816.   temp := '            ';  { 12 spaces }
  817.   y := 1;
  818.   while dta_area.fname[y] <> #0 do
  819.     begin
  820.        temp[y] := dta_area.fname[y];
  821.         y := y + 1;
  822.      end;
  823.   temp[0] := chr(y);
  824.   dir_entries.fname := temp;
  825.   dir_entries.size := dta_area.sizelo1 + dta_area.sizelo2 * 256.0
  826.                     + dta_area.sizehi * 65536.0;
  827.   dir_entries.year  := 80 + (dta_area.date shr 9);
  828.   dir_entries.month := (dta_area.date and $1e0) shr 5;
  829.   dir_entries.day   := (dta_area.date and $1f);
  830.   dir_entries.hrs := dta_area.time shr 11;
  831.   dir_entries.min := (dta_area.time shl 5) shr 10;
  832. end;
  833.  
  834. function direct_find(findstr:line):boolean;
  835. var err : boolean;
  836. begin
  837.   set_dta;
  838.   err := msdos4e($3f,findstr);
  839.   if not err then showdta;
  840.   direct_find := not err;
  841. end;
  842.  
  843.   procedure dir(action,yr,mo,dy:byte);
  844.     var errcode, spos, spaces : integer;
  845.         bksz : real;
  846.         temps,tempt,filename : line;
  847.         dirfile : text;
  848.         any,found : boolean;
  849.         blksize : string[10];
  850.         test1,test2: real;
  851.     begin
  852.       any := false;
  853.       found := false;
  854.       lineout(space);
  855.       assign(dirfile,subdir + 'Dir.bbs');
  856.       {$I-}
  857.       reset(dirfile);
  858.       {$I+}
  859.       errcode := ioresult;
  860.       if errcode = 0
  861.         then begin
  862.           stringout('Directory: ');
  863.           lineout('Section ' + sect[sectnum].sectt + ':');
  864.             while (cts and (not cancelled) and (not eof(dirfile))) do
  865.               begin
  866.                 readln(dirfile,temps);
  867.                 if copy(temps,1,1) = ' ' then lineout(temps)
  868.                   else begin
  869.                     if action = 1 then any := true;
  870.                     spos := pos(' ',temps);
  871.                     if spos = 0 then tempt := temps
  872.                                 else tempt := copy(temps,1,spos);
  873.                     assign(datafile,subdir + tempt);
  874.                     {$I-} reset(datafile); {$I+}
  875.                     errcode := ioresult;
  876.                     if errcode = 0
  877.                       then begin
  878.                         bksz := 128 * longfilesize(datafile);
  879.                         str( bksz:7:0, blksize);
  880.                         close(datafile);
  881.                       end else blksize := 'MISSING';
  882.                     if action = 2 then found := direct_find(subdir + tempt);
  883.                     if ((action = 2) and (found = true)) then any := true;
  884.                     while (length(tempt) < 13) do tempt := tempt + ' ';
  885.                     if spos <> 0
  886.                       then temps := copy(temps,spos,length(temps) - spos + 1)
  887.                       else temps := '';
  888.                     if action = 1  then lineout(tempt + blksize + temps)
  889.                       else if action = 2 then begin
  890.                         test1 :=  dir_entries.day + dir_entries.month*100.0 + dir_entries.year * 10000.0;
  891.                         test2 :=  dy + mo * 100.0 + yr * 10000.0;
  892.                         if ((test1 >= test2) and found )
  893.                           then lineout(tempt + blksize + temps);
  894.                       end;
  895.                   end;
  896.             end;
  897.             close(dirfile);
  898.          end else if not any then lineout('No files found.');
  899.     end;
  900.  
  901.   procedure directory;
  902.   var y : boolean;
  903.       x : byte;
  904.       inch: char;
  905.       mo,dy,yr : byte;
  906.     begin
  907.       canstat := true;
  908.       lineout(space);
  909.       inch := getcap('<[A]ll>,[N]ew ? ');
  910.       if not (inch in ['A','N']) then inch := 'A';
  911.       case inch of
  912.         'A' : dir(1,0,0,0);
  913.         'N' : begin
  914.                 lineout(space);
  915.                 lineout('Directory of Files ON or AFTER : ');
  916.                 yr := getint(year,80,'  Year  <'+itoa(today_year)+'> ? ');
  917.                 if yr = 0 then yr := today_year;
  918.                 mo := getint(12,1,'  Month  <'+itoa(today_month)+'> ? ');
  919.                 if mo = 0 then mo := today_month;
  920.                 dy := getint(31,1,'  Day   <'+itoa(today_date)+'> ? ');
  921.                 if dy = 0 then dy := today_date;
  922.                 dir(2,yr,mo,dy);
  923.               end;
  924.       end; {case}
  925.       canstat := false;
  926.       disk_space('C');
  927.     end;
  928.  
  929.   procedure killfile;
  930.     var loop, tabloc: integer;
  931.     dirfile, tempfile: text;
  932.     temps : line;
  933.     errcode : integer;
  934.     begin
  935.       if legaltab('Kill: ')
  936.         then begin
  937.           erase(datafile);
  938.           assign(dirfile,subdir + 'DIR.BBS');
  939.           assign(tempfile,subdir + 'temp.$$$');
  940.           rewrite(tempfile);
  941.           {$I-} reset(dirfile); {$I+}
  942.           errcode := ioresult;
  943.           if errcode = 0
  944.             then begin
  945.               readln(dirfile,temps);
  946.               while not eof(dirfile) do
  947.                 begin
  948.                 if copy(temps,1,length(filename)) <> filename
  949.                     then writeln(tempfile,temps);
  950.                 readln(dirfile,temps);
  951.                 end;
  952.               if copy(temps,1,length(filename)) <> filename
  953.                   then writeln(tempfile,temps);
  954.               close(dirfile);
  955.               erase(dirfile);
  956.               close(tempfile);
  957.               rename(tempfile,subdir + 'DIR.BBS');
  958.             end;
  959.         end;
  960.     end;
  961.  
  962.   procedure installfile;
  963.     begin
  964.       if legaltab('Install : ') then
  965.         if exists(subdir + filename)
  966.           then begin
  967.             addfile;
  968.             lineout('File installed.');
  969.           end;
  970.     end;
  971.  
  972.   begin
  973.     sectnum := 10;
  974.     getsects;
  975.     clearsc;
  976.     repeat
  977.       if not expert then outfile(filemenu);
  978.       lineout(space);
  979.       lineout('Location :# '+ sect[sectnum].sectt);
  980.       comch := getcap('Files command (or ? for menu) ? ');
  981.       case comch of
  982.        '*' : getsect;
  983.        'D' : directory;
  984.        'S' : transmitfile;
  985.        'T' : textdump;
  986.        'H' : outfile(filehelp);
  987.        '?' : outfile(filemenu);
  988.        'C' : if access>newuser then begin crcmode := true; newfile(true); end;
  989.        'X' : if access>newuser then begin crcmode := false; newfile(true); end;
  990.        'A' : if access>newuser then newfile(false);
  991.        'K' : if access = sysop then killfile;
  992.        'I' : if access = sysop then installfile;
  993.       end;
  994.     until (comch = 'Q') or not cts;
  995.   end;
  996.  
  997. procedure umess_store;
  998.   begin
  999.    lineout('Please enter message here - 40 char. max');
  1000.    lineout('|--------------------------------------|');
  1001.    stringout('->');
  1002.    umess := inputstring(echo,40);
  1003.    upost := true;
  1004.   end;
  1005.  
  1006. procedure command;
  1007.   var
  1008.     prompt: line;
  1009.     inch  : char;
  1010.     first : boolean;
  1011.     byby  : boolean;
  1012.   begin
  1013.     byby := false;
  1014.     first := true;
  1015.     while cts do begin
  1016.       canstat := false;
  1017.       calcconnect(usehour,usemin);
  1018.       if ((((usehour * 60) + today_timeon + usemin) > maxminon) and (access < prefuser))
  1019.         then begin
  1020.           lineout(space);
  1021.           connecttime;
  1022.           lineout('Sorry Swab, but you time Limit is up');
  1023.           lineout('Please Dematerialize NOW!');
  1024.           update_userlog('*** TIME EXPIRED ***');
  1025.           delay(5000);
  1026.           byby := true;
  1027.         end;
  1028.       if first and not expert then outfile(mainmenu);
  1029.       canstat := false;
  1030.       prompt := 'Command : ';
  1031.       if not expert
  1032.        then prompt := prompt + 'A,B,C,D,E,F,H,I,K,L,M,N,O,P,R,S,U,W,X,Y,#,* ? '
  1033.        else prompt := prompt + '(? for menu) ? ';
  1034.       lineout(space);
  1035.       if upost
  1036.        then WriteLn(umess)
  1037.        else begin
  1038.         umess := 'Welcome!';
  1039.         WriteLn(umess);
  1040.        end;
  1041.       lineout(space);
  1042.       lineout('Location : #' + sections[subboard].sectname);
  1043.       if byby then inch := 'D' else inch := getcap(prompt);
  1044.       first := true;
  1045.       case inch of
  1046.         'A': begin
  1047.                lineout('Leave mail to user 000');
  1048.                delay(1000);
  1049.                mail;
  1050.              end;
  1051.         'B': outfile(bulletin);
  1052.         'C': chat;
  1053.         'E': if access>newuser then umess_store else first := false;
  1054.         'N': enter;
  1055.         'F': filesys;
  1056.         'D': disconnect;
  1057.         'H': outfile(helpfile);
  1058.         'I': setvideo;
  1059.         'K': deletex;
  1060.         'L': userlog;
  1061.         'M': mail;
  1062.         'O': other_bbs;
  1063.         'P': newpass;
  1064.         'R': receive;
  1065.         'S': quickscan;
  1066.         'U': listusers;
  1067.         'W': outfile(welcome);
  1068.         'X': begin expert := not expert; first := false; end;
  1069.         'Y': outfile(sysinfo);
  1070.         '#': userstats;
  1071.         '*': change_decks;
  1072.         '?': if expert then outfile(mainmenu);
  1073.         '@': if access=sysop then sysoponly else first := false;
  1074.         else first := false;
  1075.       end; {case}
  1076.     end; {while cts}
  1077.   end; {command}
  1078.  
  1079. procedure defaults;
  1080.   begin
  1081.     inmail := false;
  1082.     chatsysop := false;
  1083.     mailsent := false;
  1084.     good_signon := false;
  1085.     textopen := false;
  1086.     fillchar(last_message,sizeof(last_message),0);
  1087.     real_name := space;
  1088.     address := space;
  1089.     town_city := space;
  1090.     state_zip := space;
  1091.     phone_number := space;
  1092.     downloads := 0;
  1093.     uploads := 0;
  1094.     messages_posted := 0;
  1095.     logged_on := 0;
  1096.     subboard := 1;
  1097.     lf := lnfd;
  1098.     bl := null;
  1099.     cs := cls;
  1100.     bs := bksp;
  1101.     expert := false;
  1102.     caps := false;
  1103.     width := 80;
  1104.     access := newuser;
  1105.     init_logon := '***';
  1106.     special_access := 0;
  1107.     last_time_on := '***';
  1108.     lastmess := 0;
  1109.     caller := space;
  1110.     usernum := 0;
  1111.     messopen := false;
  1112.     filesopen := false;
  1113.     printon := false;
  1114.     inbuffer := '';
  1115.     cancelled := false;
  1116.     controls := false;
  1117.     canstat := false;
  1118.     mail_sent := 0;
  1119.     mail_rec := 0;
  1120.     msg_nailed := 0;
  1121.     msg_read := 0;
  1122.     today_date := 0;
  1123.     today_timeon := 0;
  1124.   end;
  1125.  
  1126. begin
  1127.   comport := 1;
  1128.   set_rs232_vector;
  1129.   baud := 1200;
  1130.   stopbits := 1;
  1131.   databits := 8;
  1132.   parity := 'N';
  1133.   setup;
  1134.   exitchar := space;
  1135.   local := false;
  1136.   resetbuff;
  1137.   get_config;
  1138.   defaults;
  1139.   getsections;
  1140.   clearmodem;
  1141.   awaitcall;
  1142.   if exitchar <> abort then
  1143.   begin
  1144.     repeat
  1145.       setbordercolor(1);
  1146.       clock(year,onmonth, ondate, onhour, onmin);
  1147.       timeon := time(year,onmonth, ondate, onhour, onmin);
  1148.       purgeline;
  1149.       resetbuff;
  1150.       lineout('The Ghost Ship East ' + version);
  1151.       if cts and not cancelled then outfile(welcome);
  1152.       if cts then signon(caller);
  1153.       if cts and not cancelled then outfile(bulletin);
  1154.       readmine; {Looks for mail}
  1155.       if cts then initmess;
  1156.       if cts then command;
  1157.       if good_signon then savedefaults;
  1158.       writeln('hung up...');
  1159.       if textopen then closemess;
  1160.       endcall;
  1161.       defaults;
  1162.       clearmodem;
  1163.       setbordercolor(0);
  1164.       awaitcall;
  1165.       setbordercolor(1);
  1166.     until exitchar = abort;
  1167.   end;
  1168.   setbordercolor(0);
  1169.  
  1170.   case comport of                      { disable interrupts }
  1171.    1 : begin                           { and restore old vector }
  1172.          port[$21] := port[$21] or $10;
  1173.          int4 := oldvec;
  1174.        end;
  1175.    2 : begin
  1176.          port[$21] := port[$21] or $8;
  1177.          int3 := oldvec;
  1178.        end;
  1179.   end;
  1180.  
  1181.   PORT[base+4] := $2;
  1182.   halt(2);
  1183. end.
  1184.